<template>
  <div class="app-container">
    <!-- 列表页面 -->
    <div v-show="!showReceipt">
      <el-row :gutter="10" class="mb8">
          <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
        <el-form-item label="账户" prop="accountId" style="width: 200px;">
          <el-select 
            v-model="queryParams.accountId" 
            placeholder="请选择账户" 
            clearable
            filterable
            @change="handleAccountChange">
            <el-option
              v-for="item in accountList"
              :key="item.dictValue"
              :label="item.dictLabel"
              :value="item.dictValue"
            />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-checkbox v-model="queryParams.showAll" @change="handleShowAllChange">
            显示全部
          </el-checkbox>
        </el-form-item>
      </el-form>
        <el-col :span="1.5">
          <el-button
            type="primary"
            plain
            icon="Plus"
            @click="handleAdd"
            v-hasPermi="['journal:journal:add']"
          >新增</el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="success"
            plain
            icon="Edit"
            :disabled="single"
            @click="handleUpdate"
            v-hasPermi="['journal:journal:edit']"
          >修改</el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="danger"
            plain
            icon="Delete"
            :disabled="multiple"
            @click="handleDelete"
            v-hasPermi="['journal:journal:remove']"
          >删除</el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="warning"
            plain
            icon="Download"
            @click="handleExport"
            v-hasPermi="['journal:journal:export']"
          >导出</el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="warning"
            plain
            icon="Upload"
            @click="handleImportClick"
            v-hasPermi="['journal:journal:RjImport']"
          >导入</el-button>
        </el-col>
        <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
      </el-row>

      <el-table v-loading="loading" :data="journalList" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="现金id" align="center" prop="id" v-if="queryParams.showAll" />
        <el-table-column label="日期" align="center" prop="createAt" width="180">
          <template #default="scope">
            <span>{{ parseTime(scope.row.createAt, '{y}-{m}-{d}') }}</span>
          </template>
        </el-table-column>
        <el-table-column label="关联凭证" align="center" prop="voucherId" />
        <el-table-column label="摘要" align="center" prop="abstractMsg" />
        <el-table-column label="收支类别" align="center" prop="revenueId">
          <template #default="scope">
            <span>{{ getRevenueName(scope.row.revenueId) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="收入(借方)" align="center" prop="debitAmount">
          <template #default="scope">
            {{ scope.row.debitAmount ? parseFloat(scope.row.debitAmount).toFixed(2) : '0.00' }}
          </template>
        </el-table-column>
        <el-table-column label="支出(贷方)" align="center" prop="expensesAmount">
          <template #default="scope">
            {{ scope.row.expensesAmount ? parseFloat(scope.row.expensesAmount).toFixed(2) : '0.00' }}
          </template>
        </el-table-column>
        <el-table-column label="余额" align="center" prop="balance">
          <template #default="scope">
            {{ scope.row.balance ? parseFloat(scope.row.balance).toFixed(2) : '0.00' }}
          </template>
        </el-table-column>
        <el-table-column label="往来单位" align="center" prop="contactUnitsId" />
        <el-table-column label="部门" align="center" prop="department" v-if="queryParams.showAll" />
        <el-table-column label="往来账号" align="center" prop="handlerNumber" v-if="queryParams.showAll" />
        <el-table-column label="项目" align="center" prop="project" v-if="queryParams.showAll" />
        <el-table-column label="备注" align="center" prop="notes" v-if="queryParams.showAll" />
        <el-table-column label="制单人" align="center" prop="creator" v-if="queryParams.showAll" />
        <el-table-column label="结算方式" align="center" prop="paymentMethodId" v-if="queryParams.showAll" />
        <el-table-column label="票据号" align="center" prop="billNumber" v-if="queryParams.showAll" />
        <el-table-column label="交易流水号" align="center" prop="transactionSerialNumber" v-if="queryParams.showAll" />
        <el-table-column label="日记账序号" align="center" prop="journalNumber" width="180">
          <template #default="scope">
            <el-link 
              type="primary" 
              :underline="false"
              @click="handleJournalNumberClick(scope.row)">
              {{ scope.row.journalNumber }}
            </el-link>
          </template>
        </el-table-column>
        <el-table-column label="账户" align="center" prop="accountId" v-if="queryParams.showAll" />
        <el-table-column 
          label="操作" 
          align="center" 
          width="280" 
          fixed="right">
          <template #default="scope">
            <el-button 
              link 
              type="primary" 
              icon="Edit" 
              @click="handleUpdate(scope.row)" 
              v-hasPermi="['journal:journal:edit']"
            >修改</el-button>
            <el-button 
              link 
              type="primary" 
              icon="Delete" 
              @click="handleDelete(scope.row)" 
              v-hasPermi="['journal:journal:remove']"
            >删除</el-button>
            <el-button 
              link 
              type="primary" 
              icon="Printer" 
              @click="handlePrintRow(scope.row)"
            >打印</el-button>
            <el-button 
              link 
              type="primary" 
              icon="Document" 
              @click="handleAttachment(scope.row)"
            >附件</el-button>
            <el-button 
              link 
              type="primary" 
              icon="User" 
              @click="handleResponsible(scope.row)"
            >复制</el-button>
          </template>
        </el-table-column>
      </el-table>
      
      <pagination
        v-show="total>0"
        :total="total"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="getList"
      />
    </div>

    <!-- 收款凭据页面 -->
    <div v-show="showReceipt">
      <div class="receipt-content">
        <h1 class="receipt-title">收款凭据</h1>
        
        <div class="receipt-header">
          <div class="header-left">
            <span>账户：{{ receiptData.accountId }} 现金</span>
            <span style="margin-left: 20px">币别：人民币</span>
          </div>
          <div class="header-right">
            <span>{{ formatDate(receiptData.createAt) }}</span>
            <span style="margin-left: 20px">NO.{{ receiptData.journalNumber }}</span>
          </div>
        </div>

        <div class="receipt-table">
          <table>
            <tr>
              <td class="label">摘要</td>
              <td class="value">{{ receiptData.abstractMsg }}</td>
            </tr>
            <tr>
              <td class="label">大写金额</td>
              <td class="value">
                {{ convertToChinese(getDisplayAmount(receiptData)) }}
                ({{ receiptData.debitAmount > 0 ? '收入' : '支出' }})
              </td>
            </tr>
            <tr>
              <td class="label">小写金额</td>
              <td class="value">
                {{ formatAmount(getDisplayAmount(receiptData)) }}
                ({{ receiptData.debitAmount > 0 ? '收入' : '支出' }})
              </td>
            </tr>
            <tr>
              <td class="label">往来单位</td>
              <td class="value">{{ receiptData.contactUnitsId }}</td>
            </tr>
            <tr>
              <td class="label">收支类别</td>
              <td class="value">{{ getRevenueName(receiptData.revenueId) }}</td>
            </tr>
            <tr>
              <td class="label">结算方式</td>
              <td class="value">{{ receiptData.paymentMethodId }}</td>
            </tr>
            <tr>
              <td class="label">票据号</td>
              <td class="value">{{ receiptData.billNumber }}</td>
            </tr>
            <tr>
              <td class="label">备注</td>
              <td class="value">{{ receiptData.notes }}</td>
            </tr>
          </table>
        </div>

        <div class="receipt-footer">
          <div>会计：{{ receiptData.creator }}</div>
          <div>出纳：会计{{ receiptData.creator }}</div>
          <div>经手人：</div>
        </div>
      </div>

      <div class="receipt-actions">
        <el-button @click="handleBack">返 回</el-button>
        <el-button type="primary" @click="handlePrint">打 印</el-button>
      </div>
    </div>

    <!-- 添加或修改现金日记账对话框 -->
    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
      <el-form ref="journalRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="摘要" prop="abstractMsg">
          <el-input v-model="form.abstractMsg" placeholder="请输入摘要" />
        </el-form-item>
        <el-form-item label="收支类别" prop="revenueId">
          <el-select 
            v-model="form.revenueId" 
            placeholder="请选择收支类别"
            clearable
            filterable>
            <el-option
              v-for="item in revenueList"
              :key="item.dictValue"
              :label="item.dictLabel"
              :value="item.dictValue"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="收入(借方)" prop="debitAmount">
          <el-input 
            v-model="form.debitAmount" 
            placeholder="请输入收入(借方)"
            v-input-number
          />
        </el-form-item>
        <el-form-item label="支出(贷方)" prop="expensesAmount">
          <el-input 
            v-model="form.expensesAmount" 
            placeholder="请输入支出(贷方)"
            v-input-number
          />
        </el-form-item>
        <el-form-item label="往来单位" prop="contactUnitsId">
          <el-input v-model="form.contactUnitsId" placeholder="请输入往来单位" />
        </el-form-item>
        <el-form-item label="备注" prop="notes">
          <el-input v-model="form.notes" placeholder="请输入备注" />
        </el-form-item>
        <el-form-item label="结算方式" prop="paymentMethodId">
          <el-input v-model="form.paymentMethodId" placeholder="请输入结算方式" />
        </el-form-item>
        <el-form-item label="票据号" prop="billNumber">
          <el-input v-model="form.billNumber" placeholder="请输入票据号" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 添加收款凭据对话框组件 -->
    <receipt-dialog ref="receiptDialogRef" />

    <!-- 添加账户选择对话框 -->
    <el-dialog 
      title="选择导入账户" 
      v-model="accountSelectOpen" 
      width="400px" 
      append-to-body>
      <el-form label-width="80px">
        <el-form-item label="账户" prop="accountId">
          <el-select 
            v-model="upload.data.accountId" 
            placeholder="请选择账户" 
            clearable
            filterable>
            <el-option
              v-for="item in accountList"
              :key="item.dictValue"
              :label="item.dictLabel"
              :value="item.dictValue"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleAccountSelect">确 定</el-button>
          <el-button @click="accountSelectOpen = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 修改原导入对话框，移除账户选择部分 -->
    <el-dialog :title="导入现金日记账" v-model="importOpen" width="400px" append-to-body>
      <el-upload
        ref="uploadRef"
        :limit="1"
        accept=".xlsx, .xls"
        :headers="upload.headers"
        :action="upload.url"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :on-error="handleFileError"
        :auto-upload="false"
        :method="upload.method"
        :data="upload.data"
        drag
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的数据
            <el-link type="primary" :underline="false" style="font-size:12px;margin-left:12px" @click="importTemplate">下载模板</el-link>
          </div>
          <div class="el-upload__tip" style="color:red">提示：仅允许导入"xls"或"xlsx"格式文件！</div>
        </template>
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitFileForm">确 定</el-button>
          <el-button @click="importOpen = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="Journal">
import { ref, reactive, toRefs, onMounted, getCurrentInstance, watch } from 'vue'
import { listJournal, getJournal, delJournal, addJournal, updateJournal, listAcount, listCategories } from "@/api/journal/journal";
import ReceiptDialog from './receipt-dialog.vue'
import { useRouter } from 'vue-router'
import { parseTime } from '@/utils/ruoyi'
import { UploadFilled } from '@element-plus/icons-vue'
import { getToken } from "@/utils/auth";

const { proxy } = getCurrentInstance();
const router = useRouter();

const journalList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const accountList = ref([]);
const revenueList = ref([]);
const showReceipt = ref(false)
const receiptData = ref({})
const importOpen = ref(false);
const uploadRef = ref();
const upload = reactive({
  open: false,
  title: "",
  isUploading: false,
  updateSupport: false,
  headers: { Authorization: "Bearer " + getToken() },
  url: "",
  method: 'POST',
  data: {
    updateSupport: false,
    accountId: null
  }
});

const accountSelectOpen = ref(false);

const data = reactive({
  form: {
    id: null,
    createAt: null,
    voucherId: null,
    abstractMsg: null,
    revenueId: null,
    debitAmount: null,
    expensesAmount: null,
    balance: null,
    contactUnitsId: null,
    department: null,
    handlerNumber: null,
    project: null,
    notes: null,
    creatorId: null,
    creator: null,
    paymentMethodId: null,
    billNumber: null,
    transactionSerialNumber: null,
    journalNumber: null,
    accountId: 1
  },
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    accountId: null,
    showAll: false
  },
  rules: {
  }
});

const { queryParams, form, rules } = toRefs(data);

/** 查询现金日记账列表 */
function getList() {
  loading.value = true;
  const params = {
    ...queryParams.value,
    accountId: queryParams.value.showAll ? null : queryParams.value.accountId
  };
  
  listJournal(params).then(response => {
    journalList.value = response.rows;
    total.value = response.total;
    loading.value = false;
  });
}

// 取消按钮
function cancel() {
  open.value = false;
  reset();
}

// 表单重置
function reset() {
  form.value = {
    id: null,
    createAt: null,
    voucherId: null,
    abstractMsg: null,
    revenueId: null,
    debitAmount: null,
    expensesAmount: null,
    balance: null,
    contactUnitsId: null,
    department: null,
    handlerNumber: null,
    project: null,
    notes: null,
    creatorId: null,
    creator: null,
    paymentMethodId: null,
    billNumber: null,
    transactionSerialNumber: null,
    journalNumber: null,
    accountId: 1
  };
  proxy.resetForm("journalRef");
}

/** 搜索按钮操作 */
function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
}
/** 查询所有用户 */

function getAcount() {
  listAcount().then(response => {
    if (response.code === 200) {
      accountList.value = response.rows.map(item => ({
        dictValue: item.id,
        dictLabel: item.accountName
      }));
    }
  });
}

/** 查询收支类别列表 */
function getRevenue() {
  listCategories().then(response => {
    if (response.code === 200) {
      revenueList.value = response.rows.map(item => ({
        dictValue: item.id,
        dictLabel: item.categoriesName
      }));
    }
  });
}


// 多选框选中数据
function handleSelectionChange(selection) {
  ids.value = selection.map(item => item.id);
  single.value = selection.length != 1;
  multiple.value = !selection.length;
}

/** 新增按钮操作 */
function handleAdd() {
  reset();
  form.value.accountId = queryParams.value.accountId || 1;
  open.value = true;
  title.value = "添加现金日记账";
  getRevenue();
}

/** 修改按钮操作 */
function handleUpdate(row) {
  reset();
  const _id = row.id || ids.value
  getJournal(_id).then(response => {
    form.value = {
      ...response.data,
      debitAmount: response.data.debitAmount === 0 ? '' : response.data.debitAmount,
      expensesAmount: response.data.expensesAmount === 0 ? '' : response.data.expensesAmount
    };
    open.value = true;
    title.value = "修改现金日记账";
  });
}

/** 提交按钮 */
function submitForm() {
  proxy.$refs["journalRef"].validate(valid => {
    if (valid) {
      if (form.value.id != null) {
        updateJournal(form.value).then(response => {
          proxy.$modal.msgSuccess("修改成功");
          open.value = false;
          getList();
        });
      } else {
        addJournal(form.value).then(response => {
          proxy.$modal.msgSuccess("新增成功");
          open.value = false;
          getList();
        });
      }
    }
  });
}

/** 删除按钮操作 */
function handleDelete(row) {
  const _ids = row.id || ids.value;
  proxy.$modal.confirm('是否确认删除现金日记账编号为"' + _ids + '"的数据项？').then(function() {
    return delJournal(_ids);
  }).then(() => {
    getList();
    proxy.$modal.msgSuccess("删除成功");
  }).catch(() => {});
}

/** 导出按钮操作 */
function handleExport() {
  proxy.download('journal/journal/export', {
    ...queryParams.value
  }, `journal_${new Date().getTime()}.xlsx`)
}
/**导入按钮操作 */
function handleImportClick() {
  // 先打开账户选择对话框
  accountSelectOpen.value = true;
}

/** 日记账序号点击事件 */
function handleJournalNumberClick(row) {
  getJournal(row.id).then(response => {
    receiptData.value = response.data
    showReceipt.value = true
  })
}

const vInputNumber = {
  mounted(el) {
    const input = el.getElementsByTagName('input')[0];
    input.addEventListener('input', function(e) {
      let value = e.target.value;
      value = value.replace(/[^\d.]/g, '');
      const parts = value.split('.');
      if (parts.length > 2) {
        value = parts[0] + '.' + parts.slice(1).join('');
      }
      if (parts.length === 2 && parts[1].length > 2) {
        value = parts[0] + '.' + parts[1].substring(0, 2);
      }
      e.target.value = value;
      input.dispatchEvent(new Event('input'));
    });
  }
};

// 格式化日期
const formatDate = (date) => {
  return parseTime(date, '{y}年{m}月{d}日')
}

// 格式化金额
const formatAmount = (amount) => {
  if (!amount) return '0.00'
  return parseFloat(amount).toFixed(2)
}

// 金额转中文大写
const convertToChinese = (num) => {
  if(!num) return '零元整'
  const units = ['', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿']
  const cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
  
  let numStr = Number(num).toFixed(2)
  let integer = Math.floor(numStr)
  let decimal = Math.round((numStr - integer) * 100)
  
  let chineseStr = ''
  let integerStr = integer.toString()
  
  for(let i = 0; i < integerStr.length; i++) {
    let digit = parseInt(integerStr[i])
    chineseStr += cnNums[digit] + units[integerStr.length - 1 - i]
  }
  
  chineseStr += '元'
  
  if(decimal > 0) {
    let jiao = Math.floor(decimal / 10)
    let fen = decimal % 10
    if(jiao > 0) chineseStr += cnNums[jiao] + '角'
    if(fen > 0) chineseStr += cnNums[fen] + '分'
  } else {
    chineseStr += '整'
  }
  
  return chineseStr
}

// 返回列表
function handleBack() {
  showReceipt.value = false
}

// 打印功能
function handlePrint() {
  window.print()
}

function handlePrintRow(row) {
  getJournal(row.id).then(response => {
    receiptData.value = response.data
    showReceipt.value = true
  })
}

function handleAttachment(row) {
  proxy.$modal.msgInfo("附件功能开发中");
}

function handleResponsible(row) {
  proxy.$modal.msgInfo("复制设置功能开发中");
}

function handleAccountChange(value) {
  if (!queryParams.value.showAll) {
    handleQuery();
  }
}

// 添加批量操作处理函数
function handleBatchCommand(command) {
  switch (command) {
    case 'edit':
      handleUpdate();
      break;
    case 'delete':
      handleDelete();
      break;
  }
}

// 处理显示全部变化
function handleShowAllChange(value) {
  handleQuery();
}

/** 下载模板操作 */
function importTemplate() {
  proxy.download('journal/journal/RjImport', {
  }, `journal_template_${new Date().getTime()}.xlsx`)
}

/** 文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
  upload.isUploading = true;
}

/** 文件上传成功处理 */
const handleFileSuccess = (response, file, fileList) => {
  upload.isUploading = false;
  uploadRef.value.clearFiles();
  importOpen.value = false;
  accountSelectOpen.value = false;
  
  if (response.code === 200) {
    proxy.$modal.msgSuccess(response.msg);
    getList();
  } else {
    proxy.$modal.msgError(response.msg);
  }
  
  upload.data.accountId = null;
  upload.data.updateSupport = false;
}

/** 文件上传错误处理 */
const handleFileError = (error) => {
  upload.isUploading = false;
  let msg = "导入失败";
  if (error.msg) {
    msg = error.msg;
  } else if (error.response && error.response.data && error.response.data.msg) {
    msg = error.response.data.msg;
  }
  proxy.$modal.msgError(msg);
};

/** 提交上传文件 */
function submitFileForm() {
  if (!upload.data.accountId) {
    proxy.$modal.msgError("请选择账户");
    return;
  }
  
  upload.data.updateSupport = upload.updateSupport;
  
  uploadRef.value.submit();
}

// 添加账户选择确认处理函数
function handleAccountSelect() {
  if (!upload.data.accountId) {
    proxy.$modal.msgError("请选择账户");
    return;
  }
  
  upload.data.accountId = Number(upload.data.accountId);
  accountSelectOpen.value = false;
  importOpen.value = true;
  
  upload.url = `${import.meta.env.VITE_APP_BASE_API}/journal/journal/RjImport?accountId=${upload.data.accountId}`;
}

// 当导入对话框关闭时重置账户选择
watch(importOpen, (val) => {
  if (!val) {
    upload.data.accountId = null;
  }
});

// 添加获取收支类别名称的函数
function getRevenueName(id) {
  const revenue = revenueList.value.find(item => item.dictValue === id);
  return revenue ? revenue.dictLabel : id;
}

// 获取要显示的金额（收入或支出）
const getDisplayAmount = (data) => {
  if (data.debitAmount > 0) {
    return data.debitAmount; // 收入金额
  } else if (data.expensesAmount > 0) {
    return data.expensesAmount; // 支出金额
  }
  return 0;
}

onMounted(() => {
  getList();
  getAcount();
  getRevenue();
});
</script>

<style scoped>
/* 添加收款凭据相关样式 */
.receipt-content {
  width: 800px;
  margin: 0 auto;
  min-height: 500px;
  padding: 40px;
  border: 1px solid #ddd;
  background: #fff;
}

.receipt-title {
  text-align: center;
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 30px;
}

.receipt-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
  padding: 10px 0;
  border-bottom: 1px solid #ddd;
}

.receipt-table {
  margin: 20px 0;
}

table {
  width: 100%;
  border-collapse: collapse;
}

td {
  padding: 12px;
  border: 1px solid #ddd;
}

.label {
  width: 120px;
  background-color: #f8f8f8;
  text-align: right;
  font-weight: bold;
}

.value {
  text-align: left;
  padding-left: 20px;
}

.receipt-footer {
  display: flex;
  justify-content: space-between;
  margin-top: 50px;
  padding-top: 20px;
  border-top: 1px solid #ddd;
}

.receipt-actions {
  text-align: center;
  margin-top: 20px;
}

@media print {
  .receipt-actions {
    display: none;
  }
  
  .receipt-content {
    border: none;
    padding: 0;
  }
}
</style>
